package com.millstein.strategy.impl;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.millstein.config.AlipayConfig;
import com.millstein.enums.order.ClientTypeEnum;
import com.millstein.enums.order.PayTypeEnum;
import com.millstein.exception.BizException;
import com.millstein.properties.AlipayProperties;
import com.millstein.strategy.PayStrategy;
import com.millstein.vo.PayInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;

import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
 * @description:
 * @author: tsing
 * @create: 2021-09-29 15:06
 */
@Service
@Slf4j
@EnableConfigurationProperties(AlipayProperties.class)
public class AlipayStrategy implements PayStrategy {

    @Autowired
    private AlipayProperties alipayProperties;

    /**
     * 策略名称
     *
     * @return
     */
    @Override
    public PayTypeEnum type() {
        return PayTypeEnum.ALIPAY;
    }

    /**
     * 下单
     *
     * @param payInfoVO 订单的信息
     * @return
     */
    @Override
    public String placeOrder(PayInfoVO payInfoVO) {
        String encodeTitle = null;
        String encodeDescription = null;
        try {
            encodeTitle = URLEncoder.encode(payInfoVO.getTitle(), "utf-8");
            encodeDescription = URLEncoder.encode(payInfoVO.getDescription(), "utf-8");
        } catch (Exception ignored) {}

        Map<String, Object> content = new HashMap<>();
        content.put("out_trade_no", payInfoVO.getOutTradeNo());
        content.put("product_code", "FAST_INSTANT_TRADE_PAY");
        //订单总金额，单位为元，精确到小数点后两位
        content.put("total_amount", payInfoVO.getPayFee());
        //商品标题/交易标题/订单标题/订单关键字等。 注意：不可使用特殊字符，如 /，=，&amp; 等。
        content.put("subject", encodeTitle);
        //商品描述，可空
        content.put("body", encodeDescription);
        // 该笔订单允许的最晚付款时间，逾期将关闭交易。取值范围：1m～15d。m-分钟，h-小时，d-天，1c-当天（1c-当天的情况下，无论交易何时创建，都在0点关闭）。 该参数数值不接受小数点， 如 1.5h，可转换为 90m。
        long timeoutMin = payInfoVO.getOrderPayTimeoutMills() / (1000 * 60);
        // 二次支付才会用到的判断，判断该订单能不能继续支付
        if (timeoutMin < 1) {
            throw new BizException(50000, "支付已超时");
        }
        content.put("timeout_express", timeoutMin + "m");

        String form = "";
        try {
            if (payInfoVO.getClientType().equals(ClientTypeEnum.H5.name())) {
                // 网页端
                AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
                request.setBizContent(JSON.toJSONString(content));
                request.setNotifyUrl(alipayProperties.getCallbackUrl());
                request.setReturnUrl(alipayProperties.getSuccessRedirectUrl());
                AlipayTradeWapPayResponse response = AlipayConfig.getInstance().pageExecute(request);
                if(response.isSuccess()){
                    log.info("调用成功，结果是：{}", response.getBody());
                    form = response.getBody();
                } else {
                    log.error("调用失败，原因是：{}", response.getMsg());
                }
            } else if (payInfoVO.getClientType().equals(ClientTypeEnum.APP.name())) {
                // app端
                AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
                request.setBizContent(JSON.toJSONString(content));
                request.setNotifyUrl(alipayProperties.getCallbackUrl());
                request.setReturnUrl(alipayProperties.getSuccessRedirectUrl());
                AlipayTradeAppPayResponse response = AlipayConfig.getInstance().pageExecute(request);
                if(response.isSuccess()){
                    log.info("调用成功，结果是：{}", response.getBody());
                    form = response.getBody();
                } else {
                    log.error("调用失败，原因是：{}", response.getMsg());
                }
            } // TODO 其他客户端类型

        } catch (Exception e) {
            log.error("调用失败，原因是：{}", e.getMessage());
        }
        return form;
    }

    /**
     * 查询订单状态
     *
     * @param payInfoVO 订单的信息
     * @return
     */
    @Override
    public String queryPaySuccess(PayInfoVO payInfoVO) {
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        Map<String, Object> content = new HashMap<>();
        content.put("out_trade_no", payInfoVO.getOutTradeNo());
        request.setBizContent(JSON.toJSONString(content));
        String form = "";
        try {
            AlipayTradeQueryResponse response = AlipayConfig.getInstance().execute(request);
            if(response.isSuccess()){
                log.info("调用成功，结果是：{}", response.getBody());
                form = response.getBody();
            } else {
                log.error("调用失败，原因是：{}", response.getMsg());
            }
        } catch (Exception e) {
            log.error("调用失败，原因是：{}", e.getMessage());
        }
        return form;
    }
}
